package com.toubutu.audio.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.toubutu.audio.admin.dto.AdminPageQueryComment;
import com.toubutu.audio.admin.mapper.UserMapper;
import com.toubutu.audio.admin.vo.AdminCommentVo;
import com.toubutu.audio.dto.CommentDto;
import com.toubutu.audio.dto.PageQueryCollectionDto;
import com.toubutu.audio.dto.PageQueryCommentDto;
import com.toubutu.audio.dto.UserCommentDto;
import com.toubutu.audio.entity.Collection;
import com.toubutu.audio.entity.Comment;
import com.toubutu.audio.mapper.CommentMapper;
import com.toubutu.audio.service.CommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.toubutu.audio.vo.CommentItemVo;
import com.toubutu.audio.vo.CommentVo;
import com.toubutu.audio.vo.UserInfoVo;
import com.toubutu.common.PageUtils;
import com.toubutu.constants.BaseConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 戒躁
 * @since 2024-01-08
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private UserMapper userMapper;

    @Override
    public PageUtils<AdminCommentVo> adminPageQueryComment(AdminPageQueryComment adminPageQueryComment) {
        LambdaQueryWrapper<Comment> wrapper = adminPageQueryComment.getWrapper();
        Page<Comment> page = adminPageQueryComment.getPage();
        page = page(page,wrapper);
        List<Comment> records = page.getRecords();
        if (records.isEmpty()){
            return new PageUtils<AdminCommentVo>(Collections.emptyList(),page);
        }
        List<Long> userIds = records.stream().map(Comment::getUserId).collect(Collectors.toList());
        Map<Long, UserInfoVo> userInfo = getUserInfo(userIds);
        List<AdminCommentVo> result = records.stream().map(c -> {
            AdminCommentVo adminCommentVo = new AdminCommentVo();
            BeanUtils.copyProperties(c, adminCommentVo);
            adminCommentVo.setUser(userInfo.get(c.getUserId()));
            return adminCommentVo;
        }).collect(Collectors.toList());
        return new PageUtils<AdminCommentVo>(result,page);
    }

    @Override
    public PageUtils<CommentVo> getCommentList(PageQueryCommentDto dto) {
        LambdaQueryWrapper<Comment> wrapper = dto.getWrapper();
        Page<Comment> page = dto.getPage();
        page = page(page,wrapper);
        List<Comment> records = page.getRecords();
        if (records.isEmpty()){
            return new PageUtils<>(Collections.emptyList(), page);
        }
        List<Long> userIds = new ArrayList<>();
        //查询所有评论的用户id
        for (Comment comment : records) {
            userIds.add(comment.getUserId());
            if (comment.getReplyUserId()!=null){
                userIds.add(comment.getReplyUserId());
            }
        }
        Map<Long, UserInfoVo> userInfoVoMap = getUserInfo(userIds);
        List<CommentVo> commentVoList = records.stream().map(comment -> {
            CommentVo commentVo = new CommentVo();
            BeanUtils.copyProperties(comment, commentVo);
            setCommentUserInfo(userInfoVoMap, commentVo);
            PageQueryCommentDto queryReplyDto = new PageQueryCommentDto();
            queryReplyDto.setParentId(comment.getId());
            queryReplyDto.setVideoCode(comment.getVideoCode());
            PageUtils<CommentVo> replyCommentList = getReplyCommentList(queryReplyDto);
            commentVo.setChildren(replyCommentList);
            return commentVo;
        }).collect(Collectors.toList());
        //重新查询该视频评论总数
        Long videoCommentCount = commentMapper.getVideoCommentCount(dto.getVideoCode());
        page.setTotal(videoCommentCount);
        return new PageUtils<CommentVo>(commentVoList,page);
    }


    private void setCommentUserInfo(Map<Long, UserInfoVo> userInfoVoMap,CommentVo commentVo){
        commentVo.setUser(userInfoVoMap.get(commentVo.getUserId()));
        if (commentVo.getReplyUserId()!=null){
            commentVo.setReplyToUser(userInfoVoMap.get(commentVo.getReplyUserId()));
        }

    }

    private Map<Long,UserInfoVo> getUserInfo(List<Long> userId){
        return userMapper.getUserInfoByUserIds(userId).stream().collect(Collectors.toMap(u->u.getUserId(),u->u,(n,o)->n));
    }
    @Override
    public PageUtils<CommentVo> getReplyCommentList(PageQueryCommentDto dto) {
        LambdaQueryWrapper<Comment> wrapper = dto.getWrapper();
        Page<Comment> page = dto.getPage();
        page = page(page, wrapper);
        List<Comment> records = page.getRecords();
        if (records.isEmpty()){
            return new PageUtils<>(Collections.emptyList(),page);
        }
        List<Long> userIds = new ArrayList<>();
        for (Comment comment : records) {
            userIds.add(comment.getUserId());
            if (comment.getReplyUserId()!=null){
                userIds.add(comment.getReplyUserId());
            }
        }
        Map<Long, UserInfoVo> userInfoMap = getUserInfo(userIds);
        List<CommentVo> commentVoList = records.stream().map(c -> {
            CommentVo commentVo = new CommentVo();
            BeanUtils.copyProperties(c, commentVo);
            setCommentUserInfo(userInfoMap,commentVo);
            return commentVo;
        }).collect(Collectors.toList());
        return new PageUtils<CommentVo>(commentVoList,page);
    }

    @Override
    public void publishComment(CommentDto commentDto) {
        Comment comment = commentDto.toPo();
        save(comment);
    }

    @Override
    public PageUtils<CommentItemVo> getUserCommentList(UserCommentDto dto) {
        LambdaQueryWrapper<Comment> wrapper = dto.getWrapper();
        Page<Comment> page = dto.getPage();
        page = page(page,wrapper);
        List<Comment> records = page.getRecords();
        if (records.isEmpty()){
            return new PageUtils<CommentItemVo>(Collections.emptyList(),page);
        }
        List<CommentItemVo> commentItemVos = records.stream().map(r -> {
            CommentItemVo commentItemVo = new CommentItemVo();
            BeanUtils.copyProperties(r, commentItemVo);
            return commentItemVo;
        }).collect(Collectors.toList());
        return new PageUtils<CommentItemVo>(commentItemVos,page);
    }

    @Override
    public void deleteCommentById(Integer commentId) {
        LambdaUpdateWrapper<Comment> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Comment::getId,commentId)
                .or()
                .in(Comment::getParentId,commentId)
                .set(Comment::getIsDelete, BaseConstants.DELETED);
        update(wrapper);
    }
}
